<template>
  <div class="xtx-city" ref="target">
    <div class="select" @click="toggle()" :class="{active:visible}">
      <span v-if="!fullLocation" class="placeholder">请选择配送地址</span>
      <span v-else class="value">{{fullLocation}}</span>
      <i class="iconfont icon-angle-down"></i>
    </div>
    <div class="option" v-if="visible">
        <div v-if="loading" class="loading"></div>
      <template v-else>
        <span class="ellipsis" @click="changeItem(item)" v-for="item in currList" :key="item.code">{{item.name}}</span>
      </template>

    </div>
  </div>
</template>
<script>
import {computed, reactive, ref} from 'vue'
import { onClickOutside } from '@vueuse/core'
import axios from 'axios'
export default {
    name:'XtxCity',
    props:{
      fullLocation:{
        type:String,
        default:''
      }
    },
    setup(props,{emit}) {
        //显示和隐藏数据
        const visible=ref(false)
         //正在加载数据
        const loading=ref(false)
        //所有的省市区数据
        const allCityData=ref([])

        //提供打开函数
        const open=()=>{
            visible.value=true
            loading.value=true
            //获取地区数据
            getCityData().then(data=>{
                // console.log(data);

                allCityData.value=data
                loading.value=false

            })
            //清空之前的选择
            for(const key in changeResult){
              changeResult[key]=''
            }
        }
        //提供关闭函数
        const close=()=>{
            visible.value=false
        }
        //提供一个切换函数给select使用
        const toggle=()=>{
            visible.value?close():open()
        }
        //实现点击组件外部元素进去关闭操作
        const target=ref(null)
        onClickOutside(target,()=>{
            //参数1：监听哪个元素
            //参数2：点击了该元素外的其他地方所触发的事件
            // console.log('点击了外部参数');
            close()
        })

        //实现计算属性：获取当前显示的地区数组
        const currList=computed(()=>{
            let list=allCityData.value
            //可能市一级
            if(changeResult.provinceCode &&changeResult.provinceName){
              list=list.find(p=>p.code===changeResult.provinceCode).areaList
            }
            //可能县地区一级
            if(changeResult.cityCode && changeResult.cityName){
              list=list.find(p=>p.code===changeResult.cityCode).areaList
            }
            return list
        })

        //定义选择的省市区数据
        const changeResult=reactive({
          provinceCode:'',
          provinceName:'',
          cityCode:'',
          cityName:'',
          countyCode:'',
          countyName:'',
          fullLocation:''
        })

        //当你点击按钮时记录
        const changeItem=(item)=>{
          if(item.level===0){
            changeResult.provinceCode=item.code
            changeResult.provinceName=item.name
          }
          if(item.level===1){
            changeResult.cityCode=item.code
            changeResult.cityName=item.name
          }
          if(item.level===2){
            changeResult.countyCode=item.code
            changeResult.countyName=item.name
            //完整数据
            changeResult.fullLocation=`${changeResult.provinceName} ${changeResult.cityName} ${changeResult.countyName}`
            //这是最后一级，选完了。关闭对话框，并且通知父组件数据
            close()
            emit('change',changeResult)
          }
        }
        return {visible,toggle,target,loading,currList,changeItem}
    },
}
    //获取省市区数据函数
    const getCityData=()=>{
        // 数据：https://yjy-oss-files.oss-cn-zhangjiakou.aliyuncs.com/tuxian/area.json
        //1.当本地没有缓存，发请求获取数据
        //2.当本地有缓存，取出本地数据
        //返回promise在then获取数据，这里可能是异步操作可能输同步操作
        return new Promise((resolve,reject)=>{
            //约定：数据存储在window上的cityData字段
            if(window.cityData){
                resolve(window.cityData)
            }
            else{
                const url='https://yjy-oss-files.oss-cn-zhangjiakou.aliyuncs.com/tuxian/area.json'
                axios.get(url).then(res=>{
                    //缓存
                    window.cityData=res.data
                    resolve(res.data)
                })
            }
        })
    }
</script>
<style lang="less" scoped>
.xtx-city {
  display: inline-block;
  position: relative;
  z-index: 400;
  .select {
    border: 1px solid #e4e4e4;
    height: 30px;
    padding: 0 5px;
    line-height: 28px;
    cursor: pointer;
    &.active {
      background: #fff;
    }
    .placeholder {
      color: #999;
    }
    .value {
      color: #666;
      font-size: 12px;
    }
    i {
      font-size: 12px;
      margin-left: 5px;
    }
  }
  .option {
    width: 542px;
    border: 1px solid #e4e4e4;
    position: absolute;
    left: 0;
    top: 29px;
    background: #fff;
    min-height: 30px;
    line-height: 30px;
    display: flex;
    flex-wrap: wrap;
    padding: 10px;
    > span {
      width: 130px;
      text-align: center;
      cursor: pointer;
      border-radius: 4px;
      padding: 0 3px;
      &:hover {
        background: #f5f5f5;
      }
    }
     .loading {
      height: 290px;
      width: 100%;
      background: url(../../assets/image/loading.gif) no-repeat center;
    }
  }
}
</style>
